---
title: "ecolRxC accuracy with IPF"
author: " "
date: ' '
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

## Note

The packages **ei.Datasets** and **ecolRxC** need to be installed to this code to run. 

## Introduction

This document summarises the accuracy of the estimates attained with the function **ecolRxC()** of the **ecolRxC** package with argument ``method = "IPF"` when applied to the datasets available in **ei.Datasets**.

The cross-distribution matrices are estimated at the constituency level for the 2007 Scottish Parliamentary Elections (Scottish Parliamentary Elections, May 3, 2007), 73 matrices, using the data available in the object ei_SCO_2007 and the 2002-2020 NZ elections, 492 matrices, available in the ei_NZ_ objects.

All in all, a total of 565 transfer matrices are estimated, for which the true transfer matrices are known. The comparison with the real values is made using the error and the discrepancy and quadratic indexes (see following equations), which are calculated by the **EI()**, **EPW()** and **EQ()** functions. The number of voting matrices for each election is detailed in the attached table.

| Elección | Número de matrices |
|:--------:|:----------------:|
| 2020     |   72             | 
| 2017     |   71             |  
| 2014     |   71             |  
| 2011     |   70             |  
| 2008     |   70             |  
| 2007     |   73             | 
| 2005     |   69             |  
| 2002     |   69             |  


Regarding the election options considered in votes for parties and in votes for candidates, this study is based on imposing having obtained a minimum of **3%** of the votes. Those options that did not overcome this barrier have been grouped under the "others" option. Likewise, parties are considered in rows and candidates in columns.


## Notation

- $x_{ij}$ votes gained in unit *i* by party *j* (*j = 1,...,J*, *i = 1,...,I*).
- $y_{ik}$ votes obtained in unit *i* by candidate *k* (*k = 1,...,K*, *i = 1,...,I*).
- $v_{jk}$ voters in the district who choose party *j* and candidate *k*.
- $v^{*}_{jk}$ estimate of the number of voters in the district who choose party *j* and candidate *k*.
- $v_{j.} = \sum_{k=1}^{K}v_{jk} = \sum_{i=1}^{I}x_{ij}$ number of voters in the district who choose party *j*.
- $v_{.k} = \sum_{j=1}^{J}v_{jk} = \sum_{i=1}^{I}y_{ik}$ number of voters in the district who choose candidate *k*.
- $x_{i.} = \sum_{j=1}^{J}v_{ij} = \sum_{k=1}^{K}y_{ik} = y_{i.}$ number of voters in electoral unit *i*.
- $p_{jk}$ proportion of voters in the district who choose candidate *k* among those who chose party *j*,
$p_{jk} = v_{jk}/v_{j.} = p_{k|j}$
- $p^{*}_{jk}$ estimate proportion of voters in the district who choose candidate *k* among those who chose party *j*, $p^{*}_{jk} = v^{*}_{jk}/v_{j.} = p^{*}_{k|j}$
- $p_{j.}$ proportion of voters in the district who choose party *j*, $p_{j.} = \frac{v_{j.}}{\sum_{j}v_{j.}}$
- $p_{.k}$ proportion of voters in the district who choose candidate *k*: $p_{.k} = \frac{v_{.k}}{\sum_{k}v_{.k}}$



## **EI()** Error-index, **EPW()** Discrepancy-index and **EQ()** Quadratic- index.

The accuracy of the estimates is assessed by comparing actual and estimates values using the Error Index:

$EI = 100\frac{0.5\sum_{j,k}|v_{jk}-v_{jk}^{*}|}{\sum_{j,k}v_{jk}}$

$EPW = 100\frac{\sum_{j,k} v_{jk}|p_{jk}-p_{jk}^{*}|}{\sum_{j,k} v_{jk}}$

$EQ = 100\frac{\sqrt{\sum_{j,k} (v_{jk}-v_{jk}^{*})^{2}}}{\sum_{j,k}v_{jk}}$

- $v_{jk}$ voters in the district who choose party *j* and candidate *k*.
- $v^{*}_{jk}$ estimate of the number of voters in the district who choose party *j* and candidate *k*.
- $p_{jk}$ proportion of voters in the district who choose candidate *k* among those who chose party *j* .
- $p^{*}_{jk}$ estimate of the proportion of voters in the district who choose candidate *k* among those who chose party *j* .

```{r}
EI <- function(real, estimada, marginal){
  real <- real/rowSums(real)*marginal
  estimada <- estimada/rowSums(estimada)*marginal
  output <- 100*sum(abs(real - estimada))*.5/sum(marginal)
  return(output)
}
```

```{r}
EPW <- function(real, estimada, marginal){
  real <- real/rowSums(real)
  estimada <- estimada/rowSums(estimada)
  output <- 100*sum(real*marginal*abs(real - estimada))/sum(marginal)
  return(output)
}

```

```{r}
EQ <- function(real, estimada, marginal){
  real <- real/rowSums(real)*marginal
  estimada <- estimada/rowSums(estimada)*marginal
  output <- 100*sqrt(sum((real - estimada)^2))/sum(marginal)
  return(output)
}
```

## Summary statistics

#### summary_ecolRxC_solutions_IPF.csv

To assess the accuracy of the solutions, a battery of statistics is kept:

* **year**: *year* to which the estimated-actual comparison corresponds.
* **district**: Name of the district for which estimates belong to.
* **EI.ecolRxC.logit**: *error index*, coefficient *EI* obtained combining the local estimates attained using **ecolRxC()** with the logit transformation scale.
* **EI.ecolRxC.logit.global**: *error index*, coefficient *EI* obtained with the estimates attained using **ecolRxC()** with the logit transformation scale just considering the global relationships (equivalent to ´local = FALSE´). 
* **EI.ecolRxC.probit**: *error index*, coefficient *EI* obtained combining the local estimates attained using **ecolRxC()** with the probit transformation scale.
* **EI.ecolRxC.probit.global**: *error index*, coefficient *EI* obtained with the estimates attained using **ecolRxC()** with the probit transformation scale just considering the global relationships (equivalent to ´local = FALSE´).
* **EI.ecolRxC.logit.Yule**: *error index*, coefficient *EI* obtained combining the local estimates attained using **ecolRxC()** with the logit transformation scale and using the Yule approximation.
* **EI.ecolRxC.logit.global.Yule**: *error index*, coefficient *EI* obtained with the estimates attained using **ecolRxC()** with the logit transformation scale and using the Yule approximation, just considering the global relationships (equivalent to ´local = FALSE´). 
* **EI.ecolRxC.probit.Yule**: *error index*, coefficient *EI* obtained combining the local estimates attained using **ecolRxC()** with the probit transformation scale and using the Yule approximation..
* **EI.ecolRxC.probit.global.Yule**: *error index*, coefficient *EI* obtained with the estimates attained using **ecolRxC()** with the probit transformation scale and using the Yule approximation, just considering the global relationships (equivalent to ´local = FALSE´).


* **EPW.ecolRxC.logit**: *discrepancy index*, coefficient *EPW* obtained combining the local estimates attained using **ecolRxC()** with the logit transformation scale.
* **EPW.ecolRxC.logit.global**: *discrepancy index*, coefficient *EPW* obtained with the estimates attained using **ecolRxC()** with the logit transformation scale just considering the global relationships (equivalent to ´local = FALSE´).
* **EPW.ecolRxC.probit**: *discrepancy index*, coefficient *EPW* obtained combining the local estimates attained using **ecolRxC()** with the probit transformation scale.
* **EPW.ecolRxC.probit.global**: *discrepancy index*, coefficient *EPW* obtained with the estimates attained using **ecolRxC()** with the probit transformation scale just considering the global relationships (equivalent to ´local = FALSE´).
* **EPW.ecolRxC.logit.Yule**: *discrepancy index*, coefficient *EPW* obtained combining the local estimates attained using **ecolRxC()** with the logit transformation scale and using the Yule approximation.
* **EPW.ecolRxC.logit.global.Yule**: *discrepancy index*, coefficient *EPW* obtained with the estimates attained using **ecolRxC()** with the logit transformation scale and using the Yule approximation, just considering the global relationships (equivalent to ´local = FALSE´).
* **EPW.ecolRxC.probit.Yule**: *discrepancy index*, coefficient *EPW* obtained combining the local estimates attained using **ecolRxC()** with the probit transformation scale and using the Yule approximation.
* **EPW.ecolRxC.probit.global.Yule**: *discrepancy index*, coefficient *EPW* obtained with the estimates attained using **ecolRxC()** with the probit transformation scale and using the Yule approximation, just considering the global relationships (equivalent to ´local = FALSE´).

* **EQ.ecolRxC.logit**: coefficient *EQ* obtained combining the local estimates attained using **ecolRxC()** with the logit transformation scale.
* **EQ.ecolRxC.logit.global**: coefficient *EQ* obtained with the estimates attained using **ecolRxC()** with the logit transformation scale just considering the global relationships (equivalent to ´local = FALSE´).
* **EQ.ecolRxC.probit**: coefficient *EQ* obtained combining the local estimates attained using **ecolRxC()** with the probit transformation scale.
* **EQ.ecolRxC.probit.global**: coefficient *EQ* obtained with the estimates attained using **ecolRxC()** with the probit transformation scale just considering the global relationships (equivalent to ´local = FALSE´).
* **EQ.ecolRxC.logit.Yule**: coefficient *EQ* obtained combining the local estimates attained using **ecolRxC()** with the logit transformation scale and using the Yule approximation.
* **EQ.ecolRxC.logit.global.Yule**: coefficient *EQ* obtained with the estimates attained using **ecolRxC()** with the logit transformation scale and using the Yule approximation, just considering the global relationships (equivalent to ´local = FALSE´).
* **EQ.ecolRxC.probit.Yule**: coefficient *EQ* obtained combining the local estimates attained using **ecolRxC()** with the probit transformation scale and using the Yule approximation.
* **EQ.ecolRxC.probit.global.Yule**: coefficient *EQ* obtained with the estimates attained using **ecolRxC()** with the probit transformation scale and using the Yule approximation, just considering the global relationships (equivalent to ´local = FALSE´).


In order to evaluate computational costs, the time that each algorithm spends in reaching the estimate is also computed.

* **time.ecolRxC.logit**: computation time (in secs) spent by the **ecolRxC()** function using the logit transformation scale.
* **time.ecolRxC.probit**: computation time (in secs) spent by the **ecolRxC()** function using the probit transformation scale.
* **time.ecolRxC.logit.Yule**: computation time (in secs) spent by the **ecolRxC()** function using the logit transformation scale and using the Yule approximation.
* **time.ecolRxC.probit.Yule**: computation time (in secs) spent by the **ecolRxC()** function using the probit transformation scale and using the Yule approximation.


#### pjk_ecolRxC_predictions_IPF.csv

* **year**: *year* to which the estimated-actual comparison corresponds.
* **district**: Name of the district for which estimates belong to.
* **votes**: *total de votes* recorded in *district* in the election held in *year*.
* **I**: *number of units* (polling stations) of the district.
* **row**: row *j* linked to estimate *p~jk~* of the transfer matrix.
* **column**: column *k* linked to estimate *p~jk~* of the transfer matrix.
* **pjk**: Actual value corresponding to *p~jk~*.
* **vjk**: Actual value corresponding to *v~jk~*.
* **pjk.ecolRxC.logit**: percentage of vote transfer estimate from party *j* to candidate *k* attained combining the local estimates with **ecolRxC()** with the logit transformation scale.
* **pjk.ecolRxC.logit.global**: percentage of vote transfer estimate from party *j* to candidate *k* attained with **ecolRxC()** with the logit transformation scalejust considering the global relationships (equivalent to ´local = FALSE´). 
* **pjk.ecolRxC.probit**: percentage of vote transfer estimate from party *j* to candidate *k* attained combining the local estimates with **ecolRxC()** with the probit transformation scale.
* **pjk.ecolRxC.probit.global**: percentage of vote transfer estimate from party *j* to candidate *k* attained with **ecolRxC()** with the probit transformation scale just considering the global relationships (equivalent to ´local = FALSE´). 
* **pjk.ecolRxC.logit.Yule**: percentage of vote transfer estimate from party *j* to candidate *k* attained combining the local estimates with **ecolRxC()** with the logit transformation scale and using the Yule approximation.
* **pjk.ecolRxC.logit.global.Yule**: percentage of vote transfer estimate from party *j* to candidate *k* attained with **ecolRxC()** with the logit transformation scale and using the Yule approximation, just considering the global relationships (equivalent to ´local = FALSE´). 
* **pjk.ecolRxC.probit.Yule**: percentage of vote transfer estimate from party *j* to candidate *k* attained combining the local estimates with **ecolRxC()** with the probit transformation scale and using the Yule approximation.
* **pjk.ecolRxC.probit.global.Yule**: percentage of vote transfer estimate from party *j* to candidate *k* attained with **ecolRxC()** with the probit transformation scale and using the Yule approximation, just considering the global relationships (equivalent to ´local = FALSE´). 


## CODE OF COMPUTATION.

```{r, message = F, warning = F}
library(ecolRxC)
library(ei.Datasets)
```

```{r}
sessionInfo()
```

```{r}
year <- district <- EI.ecolRxC.logit <- EI.ecolRxC.logit.global <- EI.ecolRxC.probit <- 
  EI.ecolRxC.probit.global <- EI.ecolRxC.logit.Yule <- EI.ecolRxC.logit.global.Yule <- 
  EI.ecolRxC.probit.Yule <- EI.ecolRxC.probit.global.Yule <- EPW.ecolRxC.logit <- EPW.ecolRxC.logit.global <- 
  EPW.ecolRxC.probit <- EPW.ecolRxC.probit.global <- EPW.ecolRxC.logit.Yule <- EPW.ecolRxC.logit.global.Yule <-
  EPW.ecolRxC.probit.Yule <- EPW.ecolRxC.probit.global.Yule <- EQ.ecolRxC.logit <- EQ.ecolRxC.logit.global <- 
  EQ.ecolRxC.probit <- EQ.ecolRxC.probit.global <- EQ.ecolRxC.logit.Yule <- EQ.ecolRxC.logit.global.Yule <-
  EQ.ecolRxC.probit.Yule <- EQ.ecolRxC.probit.global.Yule <- time.ecolRxC.logit <- time.ecolRxC.probit <-  
  time.ecolRxC.logit.Yule <- time.ecolRxC.probit.Yule <- NULL

year2 <- district2 <- votes2 <- I2 <- row <- column <- pjk <- vjk <- pjk.ecolRxC.logit <- 
  pjk.ecolRxC.logit.global <- pjk.ecolRxC.probit <- pjk.ecolRxC.probit.global <- 
  pjk.ecolRxC.logit.Yule <- pjk.ecolRxC.logit.global.Yule <- pjk.ecolRxC.probit.Yule <-
  pjk.ecolRxC.probit.global.Yule <-NULL
```



```{r elecciones, message = F, warning = F}
bases <- c("ei_NZ_2002", "ei_NZ_2005", "ei_SCO_2007", "ei_NZ_2008", "ei_NZ_2011", "ei_NZ_2014",
           "ei_NZ_2017", "ei_NZ_2020")

for (bb in 1:length(bases)){

base.datos <- merge_small_options(get(bases[bb]), 3, 3)
anyo <- substr(bases[bb], nchar(bases[bb])-3, 999)

for (dd in 1:nrow(base.datos)){
    # Reading the data
    cruzada <- base.datos$District_cross_votes[[dd]]
    candidatos <-  base.datos$Votes_to_candidates[[dd]]
    names(candidatos) <- paste0(names(candidatos), ".c")
    partidos <-  base.datos$Votes_to_parties[[dd]]
    names(partidos) <- paste0(names(partidos), ".p")
    district0 <-  base.datos$District[dd]
    
    # Get rid off metadata of the objects
    cruzada <- cruzada[, -1]
    candidatos <- candidatos[, -c(1,2)]
    partidos <- partidos[, -c(1,2)]
    votos.p <- colSums(partidos)
    votos.c <- colSums(candidatos)
    votos.real <- cruzada
    prop.real <- votos.real/rowSums(votos.real)
    
    # To save pjk
    grid <- cbind(expand.grid(1:ncol(cruzada), 1:nrow(cruzada)))
    colnames(grid) <- c("row", "column")
    prob.real2 <- round(as.vector(as.matrix(t(prop.real*100))), 2)
    votos.real <- as.vector(t(as.matrix(round(cruzada))))
    
    #-------------------------------------------------
    # ecolRxC.logit IPF
    start.1 <- Sys.time()
      trans1 <- ecolRxC(partidos, candidatos, scale = "logit", method = "IPF", confidence = NULL)
    end.1 <- Sys.time()
    
    error.1 <- EI(prop.real, trans1$VTM, colSums(partidos))
    discr.1 <- EPW(prop.real, trans1$VTM, colSums(partidos))
    eq.1 <- EQ(prop.real, trans1$VTM, colSums(partidos))
    error.1g <- EI(prop.real, trans1$VTM.global, colSums(partidos))
    discr.1g <- EPW(prop.real, trans1$VTM.global, colSums(partidos))
    eq.1g <- EQ(prop.real, trans1$VTM.global, colSums(partidos))
    time.1 <- round(as.numeric(difftime(end.1, start.1, units = "secs")), 2)
    #-------------------------------------------------
    # ecolRxC.probit IPF
    start.2 <- Sys.time()
      trans2 <- ecolRxC(partidos, candidatos, scale = "probit", method = "IPF", confidence = NULL)
    end.2 <- Sys.time()
    
    error.2 <- EI(prop.real, trans2$VTM, colSums(partidos))
    discr.2 <- EPW(prop.real, trans2$VTM, colSums(partidos))
    eq.2 <- EQ(prop.real, trans2$VTM, colSums(partidos))
    error.2g <- EI(prop.real, trans2$VTM.global, colSums(partidos))
    discr.2g <- EPW(prop.real, trans2$VTM.global, colSums(partidos))
    eq.2g <- EQ(prop.real, trans2$VTM.global, colSums(partidos))
    time.2 <- round(as.numeric(difftime(end.2, start.2, units = "secs")), 2)
    #-------------------------------------------------
    #-------------------------------------------------
    # ecolRxC.logit.Yule
    start.3 <- Sys.time()
      trans3 <- ecolRxC(partidos, candidatos, scale = "logit", method = "IPF", 
                        confidence = NULL, Yule.aprox = TRUE)
    end.3 <- Sys.time()
    
    error.3 <- EI(prop.real, trans3$VTM, colSums(partidos))
    discr.3 <- EPW(prop.real, trans3$VTM, colSums(partidos))
    eq.3 <- EQ(prop.real, trans3$VTM, colSums(partidos))
    error.3g <- EI(prop.real, trans3$VTM.global, colSums(partidos))
    discr.3g <- EPW(prop.real, trans3$VTM.global, colSums(partidos))
    eq.3g <- EQ(prop.real, trans3$VTM.global, colSums(partidos))
    time.3 <- round(as.numeric(difftime(end.3, start.3, units = "secs")), 2)
    #-------------------------------------------------
    # ecolRxC.probit.Yule
    start.4 <- Sys.time()
      trans4 <- ecolRxC(partidos, candidatos, scale = "probit", method = "IPF",
                        confidence = NULL, Yule.aprox = TRUE)
    end.4 <- Sys.time()
    
    error.4 <- EI(prop.real, trans4$VTM, colSums(partidos))
    discr.4 <- EPW(prop.real, trans4$VTM, colSums(partidos))
    eq.4 <- EQ(prop.real, trans4$VTM, colSums(partidos))
    error.4g <- EI(prop.real, trans4$VTM.global, colSums(partidos))
    discr.4g <- EPW(prop.real, trans4$VTM.global, colSums(partidos))
    eq.4g <- EQ(prop.real, trans4$VTM.global, colSums(partidos))
    time.4 <- round(as.numeric(difftime(end.4, start.4, units = "secs")), 2)
    #-------------------------------------------------
    
    # Saving outputs summary_ecolRxC_solutions_IPF.csv
    year <- c(year, anyo)
    district <- c(district, district0)
    
    EI.ecolRxC.logit <- c(EI.ecolRxC.logit, error.1)
    EI.ecolRxC.probit <- c(EI.ecolRxC.probit, error.2)
    EI.ecolRxC.logit.global <- c(EI.ecolRxC.logit.global, error.1g)
    EI.ecolRxC.probit.global <- c(EI.ecolRxC.probit.global, error.2g)
    EI.ecolRxC.logit.Yule <- c(EI.ecolRxC.logit.Yule, error.3)
    EI.ecolRxC.probit.Yule <- c(EI.ecolRxC.probit.Yule, error.4)
    EI.ecolRxC.logit.global.Yule <- c(EI.ecolRxC.logit.global.Yule, error.3g)
    EI.ecolRxC.probit.global.Yule <- c(EI.ecolRxC.probit.global.Yule, error.4g)

    EPW.ecolRxC.logit <- c(EPW.ecolRxC.logit, discr.1)
    EPW.ecolRxC.probit <- c(EPW.ecolRxC.probit, discr.2)
    EPW.ecolRxC.logit.global <- c(EPW.ecolRxC.logit.global, discr.1g)
    EPW.ecolRxC.probit.global <- c(EPW.ecolRxC.probit.global, discr.2g)
    EPW.ecolRxC.logit.Yule <- c(EPW.ecolRxC.logit.Yule, discr.3)
    EPW.ecolRxC.probit.Yule <- c(EPW.ecolRxC.probit.Yule, discr.4)
    EPW.ecolRxC.logit.global.Yule <- c(EPW.ecolRxC.logit.global.Yule, discr.3g)
    EPW.ecolRxC.probit.global.Yule <- c(EPW.ecolRxC.probit.global.Yule, discr.4g)
    
    EQ.ecolRxC.logit <- c(EQ.ecolRxC.logit, eq.1)
    EQ.ecolRxC.probit <- c(EQ.ecolRxC.probit, eq.2)
    EQ.ecolRxC.logit.global <- c(EQ.ecolRxC.logit.global, eq.1g)
    EQ.ecolRxC.probit.global <- c(EQ.ecolRxC.probit.global, eq.2g)
    EQ.ecolRxC.logit.Yule <- c(EQ.ecolRxC.logit.Yule, eq.3)
    EQ.ecolRxC.probit.Yule <- c(EQ.ecolRxC.probit.Yule, eq.4)
    EQ.ecolRxC.logit.global.Yule <- c(EQ.ecolRxC.logit.global.Yule, eq.3g)
    EQ.ecolRxC.probit.global.Yule <- c(EQ.ecolRxC.probit.global.Yule, eq.4g)


    time.ecolRxC.logit <- c(time.ecolRxC.logit, time.1)
    time.ecolRxC.probit <- c(time.ecolRxC.probit, time.2)
    time.ecolRxC.logit.Yule <- c(time.ecolRxC.logit.Yule, time.1)
    time.ecolRxC.probit.Yule <- c(time.ecolRxC.probit.Yule, time.2)

    tabla.resumen <- data.frame(year, district, EI.ecolRxC.logit, EI.ecolRxC.logit.global,
                                EI.ecolRxC.probit, EI.ecolRxC.probit.global, 
                                EI.ecolRxC.logit.Yule, EI.ecolRxC.logit.global.Yule,
                                EI.ecolRxC.probit.Yule, EI.ecolRxC.probit.global.Yule, EPW.ecolRxC.logit, 
                                EPW.ecolRxC.logit.global, EPW.ecolRxC.probit, EPW.ecolRxC.probit.global, 
                                EPW.ecolRxC.logit.Yule, EPW.ecolRxC.logit.global.Yule, 
                                EPW.ecolRxC.probit.Yule, EPW.ecolRxC.probit.global.Yule,
                                EQ.ecolRxC.logit, EQ.ecolRxC.logit.global, EQ.ecolRxC.probit,
                                EQ.ecolRxC.probit.global, EQ.ecolRxC.logit.Yule,
                                EQ.ecolRxC.logit.global.Yule, EQ.ecolRxC.probit.Yule,
                                EQ.ecolRxC.probit.global.Yule,
                                time.ecolRxC.logit, time.ecolRxC.probit, 
                                time.ecolRxC.logit.Yule, time.ecolRxC.probit.Yule)
    write.table(tabla.resumen, file = "summary_ecolRxC_solutions_IPF.csv", 
                sep =";", row.names = F)
    
    # Saving outputs pjk_ecolRxC_predictions_IPF.csv
    year2 <- c(year2, rep(anyo, length(votos.real)))
    district2 <- c(district2, rep(district0, length(votos.real)))
    votes2 <- c(votes2, rep(sum(partidos), length(votos.real)))
    I2 <- c(I2, rep(nrow(partidos), length(votos.real)))
    row <- c(row, grid[,2])
    column <- c(column, grid[,1])
    pjk <- c(pjk, prob.real2)
    vjk <- c(vjk, votos.real)
    pjk.ecolRxC.logit <- c(pjk.ecolRxC.logit,
                               round(as.vector(t(as.matrix(trans1$VTM)))*100, 2))
    pjk.ecolRxC.logit.global <- c(pjk.ecolRxC.logit.global,
                               round(as.vector(t(as.matrix(trans1$VTM.global)))*100, 2))
    pjk.ecolRxC.probit <- c(pjk.ecolRxC.probit,
                                 round(as.vector(t(as.matrix(trans2$VTM)))*100, 2))
    pjk.ecolRxC.probit.global <- c(pjk.ecolRxC.probit.global,
                                 round(as.vector(t(as.matrix(trans2$VTM.global)))*100, 2))
    pjk.ecolRxC.logit.Yule <- c(pjk.ecolRxC.logit.Yule,
                               round(as.vector(t(as.matrix(trans3$VTM)))*100, 2))
    pjk.ecolRxC.logit.global.Yule <- c(pjk.ecolRxC.logit.global.Yule,
                               round(as.vector(t(as.matrix(trans3$VTM.global)))*100, 2))
    pjk.ecolRxC.probit.Yule <- c(pjk.ecolRxC.probit.Yule,
                                 round(as.vector(t(as.matrix(trans4$VTM)))*100, 2))
    pjk.ecolRxC.probit.global.Yule <- c(pjk.ecolRxC.probit.global.Yule,
                                 round(as.vector(t(as.matrix(trans4$VTM.global)))*100, 2))
    tabla.resumen2 <- data.frame(year = year2, district = district2, votes = votes2, 
                                 I = I2, row, column, vjk, pjk, pjk.ecolRxC.logit,
                                 pjk.ecolRxC.logit.global, pjk.ecolRxC.probit,
                                 pjk.ecolRxC.probit.global, pjk.ecolRxC.logit.Yule,
                                 pjk.ecolRxC.logit.global.Yule, pjk.ecolRxC.probit.Yule,
                                 pjk.ecolRxC.probit.global.Yule)
    
    write.table(tabla.resumen2, file = "pjk_ecolRxC_predictions_IPF.csv", 
                sep =";", row.names = F)
 }
}
```

